package com.meatball.iot.driver.envmonitoring

import com.alibaba.fastjson2.JSON
import com.meatball.core.config.CustomThreadFactory
import com.meatball.iot.common.ClientConnectionThreadPool
import com.meatball.iot.driver.envmonitoring.data.document.EnvMonitoringDocument
import com.meatball.iot.driver.envmonitoring.enums.CoordinateTypeEnum
import com.meatball.iot.driver.envmonitoring.enums.WindDirectionAngleEnum
import com.meatball.iot.driver.envmonitoring.repository.EnvMonitoringRepository
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import rk.netDevice.sdk.p2.*
import java.util.concurrent.Executors

/**
 * TODO 环境监测仪驱动
 *
 * @property envMonitoringRepository
 *
 * @author 张翔宇
 * @since 2024年6月4日
 */
@Service
class EnvMonitoringService(
    private val envMonitoringRepository: EnvMonitoringRepository
) {
    companion object {
        private val logger = LoggerFactory.getLogger(EnvMonitoringService::class.java)
    }

    /**
     * 创建一个固定大小的线程池，用于处理客户端连接
     */
    private val executorService = ClientConnectionThreadPool.executorService()

    /**
     * TODO 系统启动后自动运行
     *
     */
    fun startServer() {
        // 初始化
        val rsServer = RSServer.Initiate(2404)
        // 注册数据监听接口
        rsServer.addDataListener(object : IDataListener {
            /**
             * TODO 实时数据接收处理
             *
             * @param p0
             */
            override fun receiveRealtimeData(p0: RealTimeData?) {
                logger.info("环境监测实时数据：${JSON.toJSONString(p0)} ")
                p0?.let {
                    executorService.execute {
                        saveData(it)
                    }
                }
            }

            /**
             * TODO 设备登陆处理
             *
             * @param p0
             */
            override fun receiveLoginData(p0: LoginData?) {
                logger.info("设备登陆：$p0")
            }

            /**
             * TODO 已存储数据接收处理
             *
             * @param p0
             */
            override fun receiveStoreData(p0: StoreData?) {
                logger.info("已存储数据接收：$p0")
            }

            /**
             * TODO 遥控指令应答处理
             *
             * @param p0
             */
            override fun receiveTelecontrolAck(p0: TelecontrolAck?) {
                logger.info("遥控指令应答：$p0")
            }

            /**
             * TODO 校时指令应答处理
             *
             * @param p0
             */
            override fun receiveTimmingAck(p0: TimmingAck?) {
                logger.info("校时指令应答：$p0")
            }

            /**
             * TODO 设备参数编号接收处理
             *
             * @param p0
             */
            override fun receiveParamIds(p0: ParamIdsData?) {
                logger.info("设备参数编号接收：$p0")
            }

            /**
             * TODO 设备参数接收处理
             *
             * @param p0
             */
            override fun receiveParam(p0: ParamData?) {
                logger.info("设备参数接收：$p0")
            }

            /**
             * TODO 下载参数后设备应答处理
             *
             * @param p0
             */
            override fun receiveWriteParamAck(p0: WriteParamAck?) {
                logger.info("下载参数后设备应答：$p0")
            }

            /**
             * TODO 透传数据后设备应答处理
             *
             * @param p0
             */
            override fun receiveTransDataAck(p0: TransDataAck?) {
                logger.info("透传数据后设备应答：$p0")
            }

            /**
             * TODO 心跳数据处理
             *
             * @param p0
             */
            override fun receiveHeartbeatData(p0: HeartbeatData?) {
                logger.info("心跳数据：$p0")
            }
        })
        rsServer.start()
    }

    /**
     * TODO 保存数据
     *
     * @param data
     */
    private fun saveData(data: RealTimeData) {
        val emd = EnvMonitoringDocument(
            deviceId = data.deviceId,
            coordinateType = CoordinateTypeEnum.fromCode(data.coordinateType),
            lat = data.lat,
            lng = data.lng,
            relayStatus = data.relayStatus,
        )
        // tem表示模拟量1 hum表示模拟量2
        data.nodeList.forEach {
            when (it.nodeId) {
                1 -> {
                    emd.windSpeedValue = it.hum
                    emd.windPowerOutput = it.tem
                }
                2 -> {
                    emd.windDirectionAngle = WindDirectionAngleEnum
                        .fromCode(if (emd.windSpeedValue > 0)  it.tem.toInt() else 99)
                    emd.windDirectionAngle360 = it.hum
                }
                11 -> {
                    emd.airTemperatureValue = it.tem
                    emd.airHumidityValue = it.hum
                }
                12 -> emd.noiseLevel = it.hum
                13 -> {
                    emd.pm10 = it.tem * 10.0F
                    emd.pm2Point5 = it.hum * 10.0F
                }
                14 -> emd.airPressureValue = it.hum
                15 -> emd.illuminationValue = it.unSignedInt32Value
                20 -> emd.cumulativeRainfallValue = it.unSignedInt32Value * 0.2F
                21 -> {
                    emd.instantRainfallValue = it.tem
                    emd.currentRainfallValue = it.hum
                }
                22 -> emd.dailyRainfallValue = it.hum
                27 -> emd.co2 = it.hum * 10.0F
            }
        }

        envMonitoringRepository.save(emd)
    }
}